package com.dff.jrfw.jsbridge;

import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Build;
import android.util.Log;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class BrowserClient extends WebViewClient {
    private final static String PROTOCOL = "nstc://";
    private final static String SCHEMA_NATIVE_FETCH_CALL = PROTOCOL + "_native_fetch_call/";
    private final static String SCHEMA_NATIVE_FETCH_CALL_RETURN = PROTOCOL + "_native_fetch_call_return/";
    private final static String SCHEMA_FOCUS = PROTOCOL + "_native_focus/";
    private static final String TAG = "BrowserClient";
    private static String jsBridge = null;

    public interface MessageHandler {
        void handleMessage(String data, MessageCallback callback);
    }

    public interface MessageCallback {
        void callback(String data);
    }


    private final Map<String, MessageHandler> handlerMap = new HashMap<>();

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        Log.d(TAG, "load complete:" + url);
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        if (handler != null) {
            handler.proceed();
        }
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
//        if (jsBridge == null) {
//            synchronized (BrowserClient.class) {
//                if (jsBridge == null) {
//                    try {
//                        StringBuilder builder = new StringBuilder();
//                        BufferedReader reader = new BufferedReader(new InputStreamReader(view.getContext().getAssets().open("JSBridge.js")));
//                        String line;
//                        do {
//                            line = reader.readLine();
//                            if (line != null && !line.matches("^\\s*//.*")) { // 去除注释
//                                builder.append(line);
//                            }
//                        } while (line != null);
//                        reader.close();
//                        jsBridge = builder.toString();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//        }
//        view.loadUrl("javascript:" + jsBridge);
        Log.d(TAG, "load start:" + url);
    }
//
//    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
//    @Override
//    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//        Log.d(TAG, "shouldOverrideUrlLoading: " + request.getUrl());
//        try {
//            String protocol = URLDecoder.decode(request.getUrl().toString(), "UTF-8");
//            if (protocol != null && protocol.startsWith(PROTOCOL)) {
//                processJSBridgeProtocol(view, protocol);
//                return true;
//            } else {
//                return super.shouldOverrideUrlLoading(view, request);
//            }
//        } catch (UnsupportedEncodingException e) {
//            return super.shouldOverrideUrlLoading(view, request);
//        }
//    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        Log.d(TAG, "shouldOverrideUrlLoading: " + url);
        try {
            String protocol = URLDecoder.decode(url, "UTF-8");
            if (protocol != null && protocol.startsWith(PROTOCOL)) {
                processJSBridgeProtocol(view, protocol);
                return true;
            } else {
                return super.shouldOverrideUrlLoading(view, url);
            }
        } catch (UnsupportedEncodingException e) {
            return super.shouldOverrideUrlLoading(view, url);
        }
    }

    public interface FocusCallBack {
        void onFocusCallBack(float percent);
    }

    private FocusCallBack focusCallBack = null;

    private void processJSBridgeProtocol(WebView view, String protocol) {
        if (protocol.startsWith(SCHEMA_NATIVE_FETCH_CALL)) {
            view.loadUrl("javascript:JSBridge._native_fetch_call();");
        } else if (protocol.startsWith(SCHEMA_NATIVE_FETCH_CALL_RETURN)) {
            String schema = protocol.substring(SCHEMA_NATIVE_FETCH_CALL_RETURN.length());
            try {
                int s1 = schema.indexOf("/");
                int s2 = schema.indexOf("/", s1 + 1);
                String handlerName = schema.substring(0, s1);
                String callbackId = schema.substring(s1 + 1, s2);
                String data = URLDecoder.decode(schema.substring(s2 + 1), "UTF-8");
                Log.d(TAG, "handlerName = " + handlerName + ",callbackId = " + callbackId + ",data = " + data);
                if (handlerName != null && callbackId != null && handlerMap.containsKey(handlerName)) {
                    Objects.requireNonNull(handlerMap.get(handlerName)).handleMessage(data, response -> {
                        Log.d(TAG, "callbackId = " + callbackId + ",response = " + response);
                        try {
                            view.loadUrl("javascript:JSBridge._native_call_return('" + callbackId + "','" + URLEncoder.encode(response.replaceAll(" ", "%20"), "UTF-8") + "');");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    });
                } else {
                    Log.d(TAG, "没有找到" + handlerName + "的处理方法");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (protocol.startsWith(SCHEMA_FOCUS)) {
            if (focusCallBack != null) {
                focusCallBack.onFocusCallBack(Float.parseFloat(protocol.replace(SCHEMA_FOCUS, "")));
                focusCallBack = null;
            }
        }
    }

    public void registerHandler(@NonNull String name, @NonNull MessageHandler handler) {
        handlerMap.put(name, handler);
    }

    public void callWeb(@NonNull WebView webView, @NonNull String handlerName, String data) {
        webView.loadUrl("javascript:JSBridge._native_call_web('" + handlerName + "','" + data + "');");
    }

    public void queryFocus(@NonNull WebView webView, @NonNull FocusCallBack focusCallBack) {
        if (this.focusCallBack == null) {
            Log.d(TAG, "queryFocus");
            this.focusCallBack = focusCallBack;
            webView.loadUrl("javascript:JSBridge._native_focus_query();");
        }
    }
}
